<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="umsroot.css">
<TITLE>
Streams
</TITLE>
</HEAD>
<BODY >
<A HREF="umsroot057.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="umsroot059.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2 CLASS="section"><A NAME="htoc135">10.1</A>&nbsp;&nbsp;Streams</H2><UL>
<LI><A HREF="umsroot058.html#toc79">Predefined Streams</A>
<LI><A HREF="umsroot058.html#toc80">Stream Identifiers and Aliases</A>
<LI><A HREF="umsroot058.html#toc81">Opening New Streams</A>
<LI><A HREF="umsroot058.html#toc82">Closing Streams</A>
<LI><A HREF="umsroot058.html#toc83">Redirecting Streams</A>
<LI><A HREF="umsroot058.html#toc84">Finding Streams</A>
<LI><A HREF="umsroot058.html#toc85">Stream Properties</A>
</UL>

<A NAME="@default504"></A> 
<A NAME="@default505"></A>
Input and output in ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> is done via communication channels
called <I>streams</I>.
They are usually associated with either a file, a terminal, a socket,
a pipe, or in-memory queues and buffers.
<A NAME="@default506"></A>
<A NAME="@default507"></A>
<A NAME="@default508"></A>
The streams may be opened for input only (<I>read mode</I>), output only
(<I>write mode</I>), or for both input and output (<I>update mode</I>).<BR>
<BR>
<A NAME="toc79"></A>
<H3 CLASS="subsection"><A NAME="htoc136">10.1.1</A>&nbsp;&nbsp;Predefined Streams</H3>
Every ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> session has 4 predefined system streams:
<A NAME="streams"></A>
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<B>stdin</B><DD CLASS="dd-description">	The standard input stream.
<A NAME="@default509"></A><BR>
<BR>
<DT CLASS="dt-description"><B>stdout</B><DD CLASS="dd-description">	The standard output stream.
<A NAME="@default510"></A><BR>
<BR>
<DT CLASS="dt-description"><B>stderr</B><DD CLASS="dd-description">	The standard error stream.
<A NAME="@default511"></A><BR>
<BR>
<DT CLASS="dt-description"><B>null</B><DD CLASS="dd-description">
<A NAME="@default512"></A>
A dummy stream, output to it is discarded, on input it always
gives end of file.
</DL>
In a stand-alone ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> stdin, stdout and stderr are connected
to the corresponding standard I/O descriptors of the process.
In an embedded ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>, the meaning of stdin, stdout and
stderr is determined by the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> initialisation options.<BR>
<BR>
Moreover, every ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> session defines the following symbolic stream
names, which are used for certain categories of input/output:
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<B>input</B><DD CLASS="dd-description">	Used by the input predicates that do not have
an explicit stream argument, e.g. <A HREF="../bips/kernel/ioterm/read-1.html"><B>read/1</B></A><A NAME="@default513"></A>.
<A NAME="@default514"></A>
<A NAME="@default515"></A>
This is by default the same as stdin, but can be redirected.<BR>
<BR>
<DT CLASS="dt-description"><B>output</B><DD CLASS="dd-description">	Used by the output predicates that do not have
an explicit stream argument, e.g. <A HREF="../bips/kernel/ioterm/write-1.html"><B>write/1</B></A><A NAME="@default516"></A>.
<A NAME="@default517"></A>
<A NAME="@default518"></A>
This is by default the same as stdout, but can be redirected.<BR>
<BR>
<DT CLASS="dt-description"><B>error</B><DD CLASS="dd-description">
Output for error messages and all messages about exceptional states.
<A NAME="@default519"></A>
This is by default the same as stderr, but can be redirected.<BR>
<BR>
<DT CLASS="dt-description"><B>warning_output</B><DD CLASS="dd-description">
Used by the system to output warning messages.
<A NAME="@default520"></A>
This is by default the same as stdout, but can be redirected.<BR>
<BR>
<DT CLASS="dt-description"><B>log_output</B><DD CLASS="dd-description">
Used by the system to output log messages, e.g. messages about garbage
collection activity.
<A NAME="@default521"></A>
This is by default the same as stdout, but can be redirected.<BR>
<BR>
<DT CLASS="dt-description"><B>user</B><DD CLASS="dd-description">
<A NAME="@default522"></A>
This identifier is provided for compatibility with Prolog
systems and it is identical with <B>stdin</B> and <B>stdout</B>
depending on the context where it is used.
</DL>
<DIV CLASS="center">
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD ALIGN=right NOWRAP>Symbolic Stream	</TD>
<TD ALIGN=left NOWRAP>	System Stream	</TD>
</TR>
<TR><TD ALIGN=right NOWRAP>input		</TD>
<TD ALIGN=left NOWRAP>	0 (stdin)	</TD>
</TR>
<TR><TD ALIGN=right NOWRAP>output		</TD>
<TD ALIGN=left NOWRAP>	1 (stdout)	</TD>
</TR>
<TR><TD ALIGN=right NOWRAP>warning_output	</TD>
<TD ALIGN=left NOWRAP>	1 (stdout)	</TD>
</TR>
<TR><TD ALIGN=right NOWRAP>log_output	</TD>
<TD ALIGN=left NOWRAP>	1 (stdout)	</TD>
</TR>
<TR><TD ALIGN=right NOWRAP>error		</TD>
<TD ALIGN=left NOWRAP>	2 (stderr)	</TD>
</TR>
<TR><TD ALIGN=right NOWRAP>		</TD>
<TD ALIGN=left NOWRAP>	3 (null)	</TD>
</TR></TABLE><BR>
Initial assignment of symbolic stream names
</DIV><BR>
<BR>
<A NAME="toc80"></A>
<H3 CLASS="subsection"><A NAME="htoc137">10.1.2</A>&nbsp;&nbsp;Stream Identifiers and Aliases</H3>
Every stream is identified by a small integer<SUP><A NAME="text14" HREF="umsroot057.html#note14">1</A></SUP>, but it can have several symbolic names (aliases), which are atoms.
Most of the built-in predicates that require a stream to be specified
have a stream argument at the first position,
e.g. <I>write(Stream, Term)</I>. This argument can be either the stream
number or a symbolic stream name.<BR>
<BR>
An alias name can be given to a stream either when it is created or
explicitly by invoking
<A HREF="../bips/kernel/iostream/set_stream-2.html"><B>set_stream/2</B></A><A NAME="@default523"></A>:
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
set_stream(Alias, Stream)
</PRE></BLOCKQUOTE>
To find the corresponding stream number, use
<A HREF="../bips/kernel/iostream/get_stream-2.html"><B>get_stream/2</B></A><A NAME="@default524"></A>:
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
get_stream(StreamOrAlias, StreamNr)
</PRE></BLOCKQUOTE>
<A HREF="../bips/kernel/iostream/get_stream-2.html"><B>get_stream/2</B></A><A NAME="@default525"></A> can also
be used to check whether two stream names are aliases of each other.<BR>
<BR>
<A NAME="toc81"></A>
<H3 CLASS="subsection"><A NAME="htoc138">10.1.3</A>&nbsp;&nbsp;Opening New Streams</H3>
<A NAME="openstream"></A>
Streams provide a uniform interface to a variety of I/O devices and
pseudo-devices. The following table gives an overview of how
streams on the different devices are opened.
<DIV CLASS="center">
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD ALIGN=center NOWRAP>I/O device	</TD>
<TD ALIGN=left NOWRAP>	How to open		</TD>
</TR>
<TR><TD ALIGN=center NOWRAP>tty		</TD>
<TD ALIGN=left NOWRAP>	implicit (stdin,stdout,stderr) or
			<A HREF="../bips/kernel/iostream/open-3.html"><B>open/3</B></A><A NAME="@default526"></A> of a device file</TD>
</TR>
<TR><TD ALIGN=center NOWRAP>file		</TD>
<TD ALIGN=left NOWRAP>	<A HREF="../bips/kernel/iostream/open-3.html"><B>open(FileName, Mode, Stream)</B></A><A NAME="@default527"></A>		</TD>
</TR>
<TR><TD ALIGN=center NOWRAP>string		</TD>
<TD ALIGN=left NOWRAP>	<A HREF="../bips/kernel/iostream/open-3.html"><B>open(string(String), Mode, Stream)</B></A><A NAME="@default528"></A>		</TD>
</TR>
<TR><TD ALIGN=center NOWRAP>queue		</TD>
<TD ALIGN=left NOWRAP>	<A HREF="../bips/kernel/iostream/open-3.html"><B>open(queue(String), Mode, Stream)</B></A><A NAME="@default529"></A>		</TD>
</TR>
<TR><TD ALIGN=center NOWRAP>pipe		</TD>
<TD ALIGN=left NOWRAP>	<A HREF="../bips/kernel/opsys/exec-2.html"><B>exec/2</B></A><A NAME="@default530"></A>,
			<A HREF="../bips/kernel/opsys/exec-3.html"><B>exec/3</B></A><A NAME="@default531"></A> and
			<A HREF="../bips/kernel/opsys/exec_group-3.html"><B>exec_group/3</B></A><A NAME="@default532"></A>	</TD>
</TR>
<TR><TD ALIGN=center NOWRAP>socket		</TD>
<TD ALIGN=left NOWRAP>	<A HREF="../bips/kernel/iostream/socket-3.html"><B>socket/3</B></A><A NAME="@default533"></A> and
			<A HREF="../bips/kernel/iostream/accept-3.html"><B>accept/3</B></A><A NAME="@default534"></A>	</TD>
</TR>
<TR><TD ALIGN=center NOWRAP>null		</TD>
<TD ALIGN=left NOWRAP>	implicit (null stream)	</TD>
</TR></TABLE><BR>
How to open streams onto the different I/O devices
</DIV><BR>
<BR>
Most streams are opened for input or output by means of the
<A HREF="../bips/kernel/iostream/open-3.html"><B>open/3</B></A><A NAME="@default535"></A>
or
<A HREF="../bips/kernel/iostream/open-4.html"><B>open/4</B></A><A NAME="@default536"></A>
predicate.
The goals
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
open(SourceSink, Mode, Stream)
open(SourceSink, Mode, Stream, Options)
</PRE></BLOCKQUOTE>
open a communication channel with <I>SourceSink</I>.<BR>
<BR>
If <I>SourceSink</I> is an atom or a string, a file is being opened
and <I>SourceSink</I> takes
the form of a file name in the host machine environment.
ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> uses an operating
system independent path name syntax, where the components are separated by
forward slashes.
The following forms are possible:
<UL CLASS="itemize"><LI CLASS="li-itemize">
absolute path name, e.g. /usr/peter/prolog/file.pl
<LI CLASS="li-itemize">relative to the current directory, e.g. prolog/file.pl
<LI CLASS="li-itemize">relative to the own home directory, e.g. <CODE>~</CODE>/prolog/file.pl
<LI CLASS="li-itemize">start with an environment variable, e.g. $HOME/prolog/file.pl
<LI CLASS="li-itemize">relative to a user's home directory, e.g. <CODE>~</CODE>peter/prolog/file.pl
	(UNIX only)
<LI CLASS="li-itemize">specifying a drive name, e.g. //C/prolog/file.pl
	(Windows only)
</UL>
Note that path names usually have to be quoted (in single or double quotes)
because they contain non-alphanumeric characters.<BR>
<BR>
If <I>SourceSink</I> is of the form <TT>string(InitString)</TT> a pseudo-file
in memory is opened, see section <A HREF="umsroot060.html#stringio">10.3.1</A>.<BR>
<BR>
If <I>SourceSink</I> is of the form <TT>queue(InitString)</TT> a pseudo-pipe
in memory is opened, see section <A HREF="umsroot060.html#queueio">10.3.2</A>.<BR>
<BR>
<I>Mode</I> must be one of the atoms <TT>read</TT>, <TT>write</TT>, <TT>append</TT> or
<TT>update</TT>,
which means that the stream is to be opened for input, output, output at the
end of the existing stream, or both input and output, respectively.
Opening a file in <TT>write</TT> mode will create it if it does not exist,
and erase the previous contents if it does exist.
Opening a file in <TT>append</TT> mode will keep the current contents
of the file and start writing at its end.<BR>
<BR>
<I>Stream</I> is a symbolic stream identifier or an uninstantiated variable.
If it is uninstantiated, the system will bind it to an identifier (the stream
number):
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
[eclipse 1]: open(new_file, write, Stream).
Stream = 6
yes.
</PRE></BLOCKQUOTE>
If the stream argument is an atomic name, this name becomes an alias
for the (hidden) stream number:
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
[eclipse 1]: open(new_file, write, new_stream).
yes.
</PRE></BLOCKQUOTE>
The stream identifier (symbolic or numeric) may then be used in predicates
which have a named stream as one of their arguments. For example
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
open("foo", update, Stream), write(Stream, subject), close(Stream).
</PRE></BLOCKQUOTE>
will write the atom
<I>subject</I> to the file `foo' and close the stream subsequently.<BR>
<BR>
It is recommended style <B>not</B> to use symbolic stream names in code that is
meant to be reused. This is because the stream names are global,
there is the possibility of name clashes, and the code will not be reentrant.
It is cleaner to open streams with a variable for the stream identifier
and pass the identifier as an argument wherever it is needed.<BR>
<BR>
<A NAME="@default537"></A>
<B>Socket</B> streams are not opened with open/3, but with the special primitives
<A HREF="../bips/kernel/iostream/socket-3.html"><B>socket/3</B></A><A NAME="@default538"></A> and
<A HREF="../bips/kernel/iostream/accept-3.html"><B>accept/3</B></A><A NAME="@default539"></A>.
More details are in chapter <A HREF="umsroot129.html#sockets">21</A>.<BR>
<BR>
<A NAME="@default540"></A>
<BR>
<BR>
A further group of primitives which open streams implicitly is
<A HREF="../bips/kernel/opsys/exec-2.html"><B>exec/2</B></A><A NAME="@default541"></A>,
<A HREF="../bips/kernel/opsys/exec-3.html"><B>exec/3</B></A><A NAME="@default542"></A> and
and <A HREF="../bips/kernel/opsys/exec_group-3.html"><B>exec_group/3</B></A><A NAME="@default543"></A>.
They open <B>pipes</B> which connect directly to the I/O channels of the
executed process. See chapter <A HREF="umsroot124.html#chapopsys">20</A> for details.<BR>
<BR>
<A NAME="toc82"></A>
<H3 CLASS="subsection"><A NAME="htoc139">10.1.4</A>&nbsp;&nbsp;Closing Streams</H3>

The predicate
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
close(Stream)
</PRE></BLOCKQUOTE>
is used to close an open stream.
If a stream has several alias names, closing any of them will close
the actual stream. All the other aliases should be closed as well
(or redirected to streams that are still open),
because otherwise they will continue
to refer to the number of the already closed stream.<BR>
<BR>
When an attempt is made to close a redirected system stream (e.g. output),
the stream is closed, but the system stream is reset to its default setting.<BR>
<BR>
<A NAME="toc83"></A>
<H3 CLASS="subsection"><A NAME="htoc140">10.1.5</A>&nbsp;&nbsp;Redirecting Streams</H3>

<A NAME="@default544"></A>
The <A HREF="../bips/kernel/iostream/set_stream-2.html"><B>set_stream/2</B></A><A NAME="@default545"></A>
primitive can be used to redirect an already existing symbolic stream
to a new actual stream.
This is particularly useful to redirect e.g. the default <B>output</B> stream
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
set_stream(output, MyStream)
</PRE></BLOCKQUOTE>
so that all standard output is redirected to some other destination
(e.g. an opened file instead of the terminal).
Note that the stream modes (read/write) must be compatible.
The redirection is terminated by calling
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
close(output)
</PRE></BLOCKQUOTE>
which will reestablish the original meaning of the output stream.<BR>
<BR>
<A NAME="toc84"></A>
<H3 CLASS="subsection"><A NAME="htoc141">10.1.6</A>&nbsp;&nbsp;Finding Streams</H3>
The predicate
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
current_stream(?Stream)
</PRE></BLOCKQUOTE>
<A NAME="@default546"></A>
can be used to backtrack over all the currently opened stream
indentifiers (but not their aliases).<BR>
<BR>
<A NAME="toc85"></A>
<H3 CLASS="subsection"><A NAME="htoc142">10.1.7</A>&nbsp;&nbsp;Stream Properties</H3>
A stream's properties can be accessed using
<A HREF="../bips/kernel/iostream/get_stream_info-3.html"><B>get_stream_info/3</B></A><A NAME="@default547"></A>
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
get_stream_info(+Stream, +Property, -Value)
</PRE></BLOCKQUOTE>
e.g. its mode, line number, file name etc.
Some stream properties can be modified using
<A HREF="../bips/kernel/iostream/set_stream_property-3.html"><B>set_stream_property/3</B></A><A NAME="@default548"></A>
<BLOCKQUOTE CLASS="quote"><PRE CLASS="verbatim">
set_stream_property(+Stream, +Property, +Value)
</PRE></BLOCKQUOTE>
e.g. the end-of-line sequence used, the flushing behaviour, the event-raising
behaviour, the prompt etc.<BR>
<BR>
<HR>
<A HREF="umsroot057.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="umsroot059.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
